// Copyright Epic Games, Inc. All Rights Reserved.

#include "Teams/AsyncAction_ObserveTeam.h"

#include "Teams/LyraTeamAgentInterface.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(AsyncAction_ObserveTeam)

/**
 * 构造函数
 */
UAsyncAction_ObserveTeam::UAsyncAction_ObserveTeam(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}

/**
 * 观察团队变化的静态方法
 */
UAsyncAction_ObserveTeam* UAsyncAction_ObserveTeam::ObserveTeam(UObject* TeamAgent)
{
	return InternalObserveTeamChanges(TeamAgent); // 调用内部观察团队变化方法
}

/**
 * 内部观察团队变化的方法
 */
UAsyncAction_ObserveTeam* UAsyncAction_ObserveTeam::InternalObserveTeamChanges(TScriptInterface<ILyraTeamAgentInterface> TeamActor)
{
	UAsyncAction_ObserveTeam* Action = nullptr; // 初始化动作为空

	if (TeamActor != nullptr) // 如果团队角色有效
	{
		Action = NewObject<UAsyncAction_ObserveTeam>(); // 创建新的观察团队动作对象
		Action->TeamInterfacePtr = TeamActor; // 设置团队接口指针
		Action->RegisterWithGameInstance(TeamActor.GetObject()); // 注册到游戏实例
	}

	return Action; // 返回创建的动作
}

/**
 * 设置准备销毁
 */
void UAsyncAction_ObserveTeam::SetReadyToDestroy()
{
	Super::SetReadyToDestroy(); // 调用父类方法

	// 如果正在取消，需要取消所有可能正在监听的钩子
	if (ILyraTeamAgentInterface* TeamInterface = TeamInterfacePtr.Get()) // 如果团队接口有效
	{
		TeamInterface->GetTeamChangedDelegateChecked().RemoveAll(this); // 移除所有监听
	}
}

/**
 * 激活异步操作
 */
void UAsyncAction_ObserveTeam::Activate()
{
	bool bCouldSucceed = false; // 初始化成功标志为false
	int32 CurrentTeamIndex = INDEX_NONE; // 当前团队索引初始化为无

	if (ILyraTeamAgentInterface* TeamInterface = TeamInterfacePtr.Get()) // 如果团队接口有效
	{
		CurrentTeamIndex = GenericTeamIdToInteger(TeamInterface->GetGenericTeamId()); // 获取当前团队索引

		TeamInterface->GetTeamChangedDelegateChecked().AddDynamic(this, &ThisClass::OnWatchedAgentChangedTeam); // 添加动态委托监听

		bCouldSucceed = true; // 设置成功标志为true
	}

	// 广播一次以便用户获取当前状态
	OnTeamChanged.Broadcast(CurrentTeamIndex != INDEX_NONE, CurrentTeamIndex); // 广播团队变化

	// 如果无法绑定到委托，我们将永远不会获得任何额外更新
	if (!bCouldSucceed) // 如果不成功
	{
		SetReadyToDestroy(); // 设置准备销毁
	}
}

/**
 * 当监视的代理团队变化时调用
 */
void UAsyncAction_ObserveTeam::OnWatchedAgentChangedTeam(UObject* TeamAgent, int32 OldTeam, int32 NewTeam)
{
	OnTeamChanged.Broadcast(NewTeam != INDEX_NONE, NewTeam); // 广播新的团队信息
}